#include "log.h"
#include "fileio.h"
#include <iostream>
#include <syncstream>
#include <sys/stat.h>
#include <string.h>
using namespace std;

Log& Log::instance()
{
    static Log log;
    return log;
}

void Log::error(const char* data)
{
    err << data;
}
void Log::output(const char* data)
{
    cout << data;
    out << data;
}
bool Log::setOutputFile(const std::string& logFile, std::ios::openmode mode)
{
    if (out.is_open()) {
        out.close();
    }

    if (logFile == "") {
        return true;
    }

    string dir = getDirName(logFile);
    if (!mkMultiDir(dir, 0755)) {
        cout << "mkdir error:" << dir << endl;
        cout << "errno:" << errno << endl
             << "error:" << strerror(errno) << endl;
    }
    out.open(logFile, mode);
    if (out.fail()) {
        cout << "errno:" << errno << endl
             << "error:" << strerror(errno) << endl;
    }
    return out.is_open();
}
bool Log::setErrorFile(const std::string& errorFile, std::ios::openmode mode)
{
    if (err.is_open()) {
        err.close();
    }

    if (errorFile == "") {
        return true;
    }

    string dir = getDirName(errorFile);
    if (!mkMultiDir(dir, 0755)) {
        cout << "mkdir error:" << dir << endl;
        cout << "errno:" << errno << endl
             << "error:" << strerror(errno) << endl;
    }
    err.open(errorFile, mode);
    if (err.fail()) {
        cout << "errno:" << errno << endl
             << "error:" << strerror(errno) << endl;
    }
    return err.is_open();
}
std::osyncstream Log::getOutput() {
    return std::osyncstream{this->out};
}
std::osyncstream Log::getError() {
    return std::osyncstream{this->err};
}

Log::~Log()
{
    out.flush();
    err.flush();
    if (out.is_open()) {
        out.close();
    }
    if (err.is_open()) {
        err.close();
    }
}